package com.fy.market.strategy.service.rule.chain.chainFactory;

import com.fy.market.strategy.model.entity.RuleModelEntity;
import com.fy.market.strategy.model.entity.StrategyEntity;
import com.fy.market.strategy.model.enums.RuleModelEnum;
import com.fy.market.strategy.repository.IStrategyRepository;
import com.fy.market.strategy.service.rule.chain.ILogicChain;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.List;
import java.util.Map;

/**
 * @author fwq
 * @date 2025-09-19
 * @desc 责任连装配工厂
 */
@Slf4j
@Service
public class LogicChainFactory {

    private final Map<String,ILogicChain> iLogicChainMap;
    protected IStrategyRepository iStrategyRepository;
    public LogicChainFactory(Map<String,ILogicChain> iLogicChainMap, IStrategyRepository iStrategyRepository){
        this.iLogicChainMap = iLogicChainMap;
        this.iStrategyRepository = iStrategyRepository;
    }

    // 组装责任链
    public ILogicChain assembleLogicChain(Integer strategyId){
        StrategyEntity strategyEntity = iStrategyRepository.getStrategyEntity(strategyId);
        List<RuleModelEntity> strategyRuleModels = strategyEntity.getStrategyRuleModels();
        if (strategyRuleModels.isEmpty()) return iLogicChainMap.get(RuleModelEnum.RULE_DEFAULT.getName());

        // 按优先级排序，确保按照策略中定义的顺序组装责任链
        strategyRuleModels.sort(Comparator.comparingInt(RuleModelEntity::getPriority));

        ILogicChain logicChain = iLogicChainMap.get(strategyRuleModels.get(0).getRuleModel());
        ILogicChain current = logicChain; // 这个是中介

        for (int i = 1; i < strategyRuleModels.size() ; i++) {
            ILogicChain next = iLogicChainMap.get(strategyRuleModels.get(i).getRuleModel());
            current.appendNext(next);
            current = next; // 移动到下一个节点
        }

        current.appendNext(iLogicChainMap.get(RuleModelEnum.RULE_DEFAULT.getName()));

        log.info("责任链组装成功,完整链条:{}",logicChain.getChainInfo());
        log.info("责任链组装成功,当前节点:{}",logicChain.getNodeName());
        return logicChain;
    }
}
